package com.chinatechstar.prediction.controller;

import java.io.IOException;
import java.util.*;

import javax.servlet.http.HttpServletResponse;

import com.chinatechstar.prediction.dto.PredictionOptimizationDTO;
import com.chinatechstar.prediction.dto.PredictionOptimizationDetailDTO;
import com.chinatechstar.prediction.entity.Trend;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.chinatechstar.prediction.entity.PredictionOptimization;
import com.chinatechstar.prediction.service.PredictionOptimizationService;
import com.chinatechstar.component.commons.result.ActionResult;
import com.chinatechstar.component.commons.result.ListResult;
import com.chinatechstar.component.commons.result.ResultBuilder;
import com.chinatechstar.component.commons.validator.InsertValidator;
import com.chinatechstar.component.commons.validator.UpdateValidator;

/**
 * 注入参数优化 的控制层
 */
@Api(value = "注入参数优化 的控制层", tags = {"注入参数优化"})
@RestController
@RequestMapping("/predictionoptimization")
public class PredictionOptimizationController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private PredictionOptimizationService predictionOptimizationService;

    /**
     * 查询 注入参数优化 所有数据
     *
     * @return ListResult<Object>
     */
    @ApiOperation(value = "查询 注入参数优化 所有数据", tags = {"注入参数优化"})
    @GetMapping(path = "/findPredictionOptimizationAll")
    public ListResult<Object> findPredictionOptimizationAll() {
        List<PredictionOptimization> list = predictionOptimizationService.findPredictionOptimizationAll();
        return ResultBuilder.buildListSuccess(list);
    }

    /**
     * 查询 注入参数优化 分页
     *
     * @param currentPage   当前页数
     * @param pageSize      每页记录数
     * @param wellName      井名
     * @param wellSeg       井段
     * @param planName      方案名
     * @param sorter        排序
     * @return ListResult<Object>
     */
    @ApiOperation(value = "查询 注入参数优化 分页", tags = {"注入参数优化"})
    @GetMapping(path = "/findPredictionOptimizationByCondition")
    public ListResult<Object> findPredictionOptimizationByCondition(@RequestParam(name = "currentPage", required = false, defaultValue = "1") Integer currentPage,
                                                           @RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize,
                                                           @RequestParam(name = "wellName", required = false) String wellName,
                                                           @RequestParam(name = "wellSeg", required = false) String wellSeg,
                                                           @RequestParam(name = "planName", required = false) String planName,
                                                           @RequestParam(name = "sorter", required = false) String sorter) {
        Map<String, Object> data = predictionOptimizationService.findPredictionOptimizationByCondition(currentPage, pageSize, wellName, wellSeg, planName, sorter);
        return ResultBuilder.buildListSuccess(data);
    }

    /**
     * 导出注入参数优化数据
     */
    @ApiOperation(value = "导出注入参数优化数据", tags = {"注入压力预测数据"})
    @GetMapping(path = "/exportPredictionOptimization")
    public void exportPredictionOptimization(HttpServletResponse response) throws IOException {
        predictionOptimizationService.exportPredictionOptimization(response);
    }

    /**
     * 根据主键ID查询 注入参数优化 数据
     *
     * @param id ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数据查询 注入参数优化 数据", tags = {"注入参数优化"})
    @GetMapping(path = "/findPredictionOptimizationById")
    public ActionResult findPredictionOptimizationById(@RequestParam(name = "id") Long id) {
        PredictionOptimization data = predictionOptimizationService.findPredictionOptimizationById(id);
        return ResultBuilder.buildActionSuccess(data);
    }

    /**
     * 根据主键ID数组查询 注入参数优化 数据
     *
     * @param ids ID数组
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数组查询 注入参数优化 数据", tags = {"注入参数优化"})
    @GetMapping(path = "/findPredictionOptimizationByIds")
    public ListResult<Object> findPredictionOptimizationByIds(@RequestParam(name = "ids") Long[] ids) {
        List<PredictionOptimization> list = predictionOptimizationService.findPredictionOptimizationByIds(ids);
        return ResultBuilder.buildListSuccess(list);
    }

    /**
     * 新增 注入参数优化
     *
     * @param predictionOptimization 注入参数优化 实体
     * @return ActionResult
     */
    @ApiOperation(value = "新增 注入参数优化", tags = {"注入参数优化"})
    @PostMapping(path = "/addPredictionOptimization")
    public ActionResult addPredictionOptimization(@Validated(InsertValidator.class) @RequestBody PredictionOptimization predictionOptimization) {
        predictionOptimizationService.insertPredictionOptimization(predictionOptimization);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 批量新增 注入参数优化
     *
     * @param predictionOptimizations 注入参数优化 实体数组
     * @return ActionResult
     */
    @ApiOperation(value = "批量新增 注入参数优化", tags = {"注入参数优化"})
    @PostMapping(path = "/addPredictionOptimizations")
    public ActionResult addPredictionOptimizations(@Validated(InsertValidator.class) @RequestBody List<PredictionOptimization> predictionOptimizations) {
        predictionOptimizationService.insertPredictionOptimizations(predictionOptimizations);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 编辑 注入参数优化
     *
     * @param predictionOptimization 注入参数优化 实体
     * @return ActionResult
     */
    @ApiOperation(value = "编辑 注入参数优化", tags = {"注入参数优化"})
    @PutMapping(path = "/updatePredictionOptimization")
    public ActionResult updatePredictionOptimization(@Validated(UpdateValidator.class) @RequestBody PredictionOptimization predictionOptimization) {
        predictionOptimizationService.updatePredictionOptimization(predictionOptimization);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 批量编辑 注入参数优化
     *
     * @param predictionOptimizations 注入参数优化 实体数组
     * @return ActionResult
     */
    @ApiOperation(value = "批量编辑 注入参数优化", tags = {"注入参数优化"})
    @PostMapping(path = "/updatePredictionOptimizations")
    public ActionResult updatePredictionOptimizations(@Validated(UpdateValidator.class) @RequestBody List<PredictionOptimization> predictionOptimizations) {
        predictionOptimizationService.updatePredictionOptimizations(predictionOptimizations);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 删除 注入参数优化
     *
     * @param id ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID删除 注入参数优化", tags = {"注入参数优化"})
    @PostMapping(path = "/deletePredictionOptimizationById")
    public ActionResult deletePredictionOptimizationById(@RequestParam(name = "id") Long id) {
        predictionOptimizationService.deletePredictionOptimizationById(id);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 删除 注入参数优化
     *
     * @param ids ID数组
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数组批量删除 注入参数优化", tags = {"注入参数优化"})
    @PostMapping(path = "/deletePredictionOptimizationByIds")
    public ActionResult deletePredictionOptimizationByIds(@RequestParam(name = "id") Long[] ids) {
        predictionOptimizationService.deletePredictionOptimizationByIds(ids);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 根据注入参数优化id获取详情或子级
     *
     * @param id 注入参数优化ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据注入参数优化id获取详情或子级", tags = {"注入参数优化"})
    @GetMapping(path = "/getOptimizationDetail")
    public ActionResult getOptimizationDetail(@RequestParam(name = "id") Long id) {
        PredictionOptimizationDetailDTO dto = predictionOptimizationService.getOptimizationDetail(id);
        return ResultBuilder.buildActionSuccess(dto);
    }

    /**
     * 计算 注入参数优化
     *
     * @param  wellName 井名
     * @param  wellType 井类型
     * @param  wellSeg  生产井段
     * @param  planName 优化方案名
     * @param  injectionLength 注入段长度
     * @param  injectionThickness 注入厚度
     * @param  formationPressure 原始地层压力
     * @param  formationTemperature 地层温度
     * @param  porosity 孔隙度
     * @param  empiricalCoefficient  经验系数
     * @param  longRadius 长轴处理半径
     */
    @ApiOperation(value = "计算 注入参数优化", tags = {"注入参数优化"})
    @PostMapping(path = "/calculatePredictionOptimization")
    public PredictionOptimization calculatePredictionOptimization(@RequestParam(name = "wellName",required = false) String wellName,
                                                     @RequestParam(name = "wellType",required = false) String wellType,
                                                     @RequestParam(name = "wellSeg",required = false) String wellSeg,
                                                     @RequestParam(name = "planName",required = false) String planName,
                                                     @RequestParam(name = "injectionLength",required = false) Double injectionLength,
                                                     @RequestParam(name = "injectionThickness",required = false) Double injectionThickness,
                                                     @RequestParam(name = "formationPressure",required = false) Double formationPressure,
                                                     @RequestParam(name = "formationTemperature",required = false) Double formationTemperature,
                                                     @RequestParam(name = "porosity",required = false) Double porosity,
                                                     @RequestParam(name = "empiricalCoefficient",required = false) Double empiricalCoefficient,
                                                     @RequestParam(name = "longRadius",required = false) Double longRadius,
                                                     @RequestParam(name = "createTime",required = false) String createTime) {
        List<PredictionOptimizationDTO> data1=new ArrayList<PredictionOptimizationDTO>();
        List<PredictionOptimizationDTO> data2=new ArrayList<PredictionOptimizationDTO>();
        double formationPressure1=Math.round(formationPressure);
        double wellBottomDensity=0;
        if(formationTemperature%5==0){
            data1=predictionOptimizationService.findWellCo2Density(formationPressure1,formationTemperature);
            data2=predictionOptimizationService.findWellCo2Density(formationPressure1,(formationTemperature+5.0));
            wellBottomDensity= data1.get(0).getCo2WellBottomDensity();
        }
        else if(data1!=null && data1.size()==0 && data2 !=null && data2.size()==0){
            data1=predictionOptimizationService.findWellCo2Density(formationPressure1,(Math.floor(formationTemperature/5)*5));
            data2=predictionOptimizationService.findWellCo2Density(formationPressure1,((Math.floor(formationTemperature/5)+1)*5));
            wellBottomDensity= Trend.trendValue(data1.get(0).getCo2WellBottomDensity(),data1.get(0).getCo2FormationTemperature(),formationTemperature,data2.get(0).getCo2WellBottomDensity(),data2.get(0).getCo2FormationTemperature());
        }
        PredictionOptimization predictionOptimization=new PredictionOptimization();
        predictionOptimization.setWellName(wellName);
        predictionOptimization.setWellType(wellType);
        predictionOptimization.setWellSeg(wellSeg);
        predictionOptimization.setPlanName(planName);
        predictionOptimization.setInjectionLength(injectionLength);
        predictionOptimization.setInjectionThickness(injectionThickness);
        predictionOptimization.setFormationPressure(formationPressure);
        predictionOptimization.setFormationTemperature(formationTemperature);
        predictionOptimization.setPorosity(porosity);
        predictionOptimization.setEmpiricalCoefficient(empiricalCoefficient);
        predictionOptimization.setLongRadius(longRadius);
        predictionOptimization.setWellBottomDensity(wellBottomDensity/1000);

        return predictionOptimizationService.calculatePredictionOptimization(predictionOptimization);
    }

}
